using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace SouthernLand.Common.Untilities
{
    public class Pager : Label, INamingContainer
    {
        private HttpContext context;
        private LinkButton firstButton;
        private LinkButton lastButton;
        private LinkButton nextButton;
        private LinkButton[] pagingLinkButtons;
        private LinkButton previousButton;

        public static int GetIntFromQueryString(HttpContext context, string key)
        {
            int returnValue = -1;
            string queryStringValue;
            queryStringValue = HttpContext.Current.Request.QueryString[key];
            if (queryStringValue == null)
                return returnValue;
            
            try
            {
                if (queryStringValue.IndexOf("#") > 0)
                    queryStringValue = queryStringValue.Substring(0, queryStringValue.IndexOf("#"));

                returnValue = Convert.ToInt32(queryStringValue);
            }
            catch
            {
            }
            return returnValue;
        }

        public int GetPageIndex()
        {
            context = HttpContext.Current;
            return 1;
        }

        public override ControlCollection Controls
        {
            get
            {
                EnsureChildControls();
                return base.Controls;
            }
        }

        public int PageIndex
        {
            get
            {
                int _pageIndex = 0;

                if (!Page.IsPostBack)
                {
                    _pageIndex = 1;
                    ViewState["PageIndex"] = 1;
                }
                else
                {
                    _pageIndex = Convert.ToInt32(ViewState["PageIndex"]);
                }


                if (_pageIndex < 0)
                    return 1;
                else
                    return _pageIndex;
            }
            set { ViewState["PageIndex"] = value; }
        }

        public int PageSize
        {
            get
            {
                int pageSize = Convert.ToInt32(ViewState["PageSize"]);
                return pageSize;
            }
            set { ViewState["PageSize"] = value; }
        }

        public int TotalRecords
        {
            get { return Convert.ToInt32(ViewState["TotalRecords"]); }
            set { ViewState["TotalRecords"] = value; }
        }

        protected override void CreateChildControls()
        {
            Controls.Clear();
            AddPageButtons();
            AddFirstLastLinkButtons();
            AddPreviousNextLinkButtons();
        }

        protected override void Render(HtmlTextWriter writer)
        {
            AddAttributesToRender(writer);
            writer.AddAttribute(HtmlTextWriterAttribute.Class, CssClass, false);
            RenderFirst(writer);
            RenderPrevious(writer);
            RenderPagingButtons(writer);
            RenderNext(writer);
            RenderLast(writer);
        }

        private void RenderFirst(HtmlTextWriter writer)
        {
            int totalPages = CalculateTotalPages();

            if ((PageIndex >= 3) && (totalPages > 5))
            {
                firstButton.RenderControl(writer);

                var l = new LiteralControl("&nbsp;...&nbsp;");
                l.RenderControl(writer);
            }
        }

        private void RenderLast(HtmlTextWriter writer)
        {
            int totalPages = CalculateTotalPages();

            if (((PageIndex + 3) < totalPages) && (totalPages > 5))
            {
                var l = new LiteralControl("&nbsp;...&nbsp;");
                l.RenderControl(writer);

                lastButton.RenderControl(writer);
            }
        }

        private void RenderPrevious(HtmlTextWriter writer)
        {
            Literal l;

            if (HasPrevious)
            {
                previousButton.RenderControl(writer);

                l = new Literal();
                l.Text = "&nbsp;";
                l.RenderControl(writer);
            }
        }

        private void RenderNext(HtmlTextWriter writer)
        {
            Literal l;

            if (HasNext)
            {
                l = new Literal();
                l.Text = "&nbsp;";
                l.RenderControl(writer);

                nextButton.RenderControl(writer);
            }
        }

        private void RenderPagingButtons(HtmlTextWriter writer)
        {
            int totalPages;
            totalPages = CalculateTotalPages();
            if (totalPages <= 5)
            {
                RenderButtonRange(0, totalPages, writer);
            }
            else
            {
                int lowerBound = (PageIndex - 2);
                int upperBound = (PageIndex + 3);

                if (lowerBound <= 0)
                    lowerBound = 0;

                if (PageIndex == 0)
                    RenderButtonRange(0, 5, writer);

                else if (PageIndex == 1)
                    RenderButtonRange(0, (PageIndex + 4), writer);

                else if (PageIndex < (totalPages - 2))
                    RenderButtonRange(lowerBound, (PageIndex + 3), writer);

                else if (PageIndex == (totalPages - 2))
                    RenderButtonRange((totalPages - 5), (PageIndex + 2), writer);

                else if (PageIndex == (totalPages - 1))
                    RenderButtonRange((totalPages - 5), (PageIndex + 1), writer);
            }
        }

        private void RenderButtonRange(int start, int end, HtmlTextWriter writer)
        {
            for (int i = start; i < end; i++)
            {
                if (PageIndex == i + 1)
                {
                    var l = new Literal();
                    l.Text = "<span class=\"CurrentPage\">" + (i + 1) + "</span>";
                    l.RenderControl(writer);
                }
                else
                {
                    pagingLinkButtons[i].RenderControl(writer);
                }
                if (i < (end - 1))
                    writer.Write(" ");
            }
        }

        private void AddPageButtons()
        {
            pagingLinkButtons = new LinkButton[CalculateTotalPages()];
            for (int i = 0; i < pagingLinkButtons.Length; i++)
            {
                pagingLinkButtons[i] = new LinkButton();
                pagingLinkButtons[i].EnableViewState = false;
                pagingLinkButtons[i].Text = (i + 1).ToString();
                pagingLinkButtons[i].ID = i.ToString();
                pagingLinkButtons[i].CommandArgument = (i + 1).ToString();
                pagingLinkButtons[i].Click += PageIndex_Click;
                Controls.Add(pagingLinkButtons[i]);
            }
        }

        private void AddFirstLastLinkButtons()
        {
            firstButton = new LinkButton();
            firstButton.ID = "First";
            firstButton.Text = "First";
            firstButton.CommandArgument = "1";
            firstButton.Click += PageIndex_Click;
            Controls.Add(firstButton);
            lastButton = new LinkButton();
            lastButton.ID = "Last";
            lastButton.Text = "Last";
            lastButton.CommandArgument = CalculateTotalPages().ToString();
            lastButton.Click += PageIndex_Click;
            Controls.Add(lastButton);
        }

        private void AddPreviousNextLinkButtons()
        {
            nextButton = new LinkButton();
            nextButton.ID = "Next";
            nextButton.Text = "Next";
            nextButton.CommandArgument = (PageIndex + 1).ToString();
            nextButton.Click += PageIndex_Click;
            Controls.Add(nextButton);
            previousButton = new LinkButton();
            previousButton.ID = "Prev";
            previousButton.Text = "Prev";
            previousButton.CommandArgument = (PageIndex - 1).ToString();
            previousButton.Click += PageIndex_Click;
            Controls.Add(previousButton);
        }

        public event EventHandler IndexChanged;

        public int CalculateTotalPages()
        {
            int totalPagesAvailable;
            if (TotalRecords == 0)
                return 0;

            // First calculate the division
            //
            totalPagesAvailable = TotalRecords/PageSize;
            // Now do a mod for any remainder
            //
            if ((TotalRecords%PageSize) > 0)
                totalPagesAvailable++;

            return totalPagesAvailable;
        }

        private bool HasPrevious
        {
            get
            {
                if (PageIndex > 1)
                    return true;

                return false;
            }
        }

        private bool HasNext
        {
            get
            {
                if (PageIndex < CalculateTotalPages())
                    return true;

                return false;
            }
        }

        private void PageIndex_Click(Object sender, EventArgs e)
        {
            PageIndex = Convert.ToInt32(((LinkButton) sender).CommandArgument);

            if (null != IndexChanged)
                IndexChanged(sender, e);
        }
    }
}